package com.wxtwxt.ruralmall.order.service.impl;

import com.wxtwxt.ruralmall.common.to.StockTo;
import com.wxtwxt.ruralmall.common.vo.MemberVo;
import com.wxtwxt.ruralmall.order.constant.OrderConstant;
import com.wxtwxt.ruralmall.order.feign.CartFeignService;
import com.wxtwxt.ruralmall.order.feign.MemberFeignService;
import com.wxtwxt.ruralmall.order.feign.WareFeginService;
import com.wxtwxt.ruralmall.order.interceptor.OrderInterceptor;
import com.wxtwxt.ruralmall.order.vo.*;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wxtwxt.ruralmall.common.utils.PageUtils;
import com.wxtwxt.ruralmall.common.utils.Query;

import com.wxtwxt.ruralmall.order.dao.OrderDao;
import com.wxtwxt.ruralmall.order.entity.OrderEntity;
import com.wxtwxt.ruralmall.order.service.OrderService;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import javax.annotation.Resource;


@Service("orderService")
public class OrderServiceImpl extends ServiceImpl<OrderDao, OrderEntity> implements OrderService {
    private static ThreadLocal<OrderSubmitVo> threadLocal;
    @Resource
    private ThreadPoolExecutor executor;
    @Resource
    private MemberFeignService memberFeignService;
    @Resource
    private CartFeignService cartFeignService;
    @Resource
    private WareFeginService wareFeginService;
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<OrderEntity> page = this.page(
                new Query<OrderEntity>().getPage(params),
                new QueryWrapper<OrderEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public OrderConfirmVo getOrderConfirmVo() {
        OrderConfirmVo orderConfirmVo = new OrderConfirmVo();
        MemberVo memberVo = OrderInterceptor.threadLocal.get();
        Long id = memberVo.getId();
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        CompletableFuture<Void> addressFuture = CompletableFuture.runAsync(() -> {
            RequestContextHolder.setRequestAttributes(requestAttributes);
            List<MemberAddressVo> address = memberFeignService.getAddress(id);
            orderConfirmVo.setAddress(address);
        }, executor);
        orderConfirmVo.setIntegration(memberVo.getIntegration());
        String token = UUID.randomUUID().toString().replace("-", "");
        orderConfirmVo.setOrderToken(token);
        stringRedisTemplate.opsForValue().set(OrderConstant.USER_ORDER_TOKEN_PREFIX + memberVo.getId(), token, 30, TimeUnit.MINUTES);
        CompletableFuture<Void> itemsFuture = CompletableFuture.runAsync(() -> {
            RequestContextHolder.setRequestAttributes(requestAttributes);
            List<OrderItemVo> cartItemList = cartFeignService.getCartItemList();
            orderConfirmVo.setItems(cartItemList);
        }, executor).thenRunAsync(() -> {
            List<OrderItemVo> items = orderConfirmVo.getItems();
            List<Long> idList = items.stream().map(item -> Long.parseLong(item.getSkuId())).collect(Collectors.toList());
            List<StockTo> stockTos = wareFeginService.stockIsExist(idList);
            if(stockTos != null && stockTos.size() > 0) {
                Map<Long, Boolean> booleanMap = stockTos.stream().collect(Collectors.toMap(StockTo::getSkuId, StockTo::getHasStock));
                orderConfirmVo.setStocks(booleanMap);
            }
        }, executor);
        try {
            CompletableFuture.allOf(addressFuture, itemsFuture).get();
        } catch (InterruptedException | ExecutionException e) {
            throw new RuntimeException(e);
        }
        return orderConfirmVo;
    }

//    @Override
//    public SubmitOrderResponseVo submitOrder(OrderSubmitVo orderSubmitVo) {
//        threadLocal.set(orderSubmitVo);
//        SubmitOrderResponseVo submitOrderResponseVo = new SubmitOrderResponseVo();
//        MemberVo memberVo = OrderInterceptor.threadLocal.get();
//        // 验证令牌
//        String orderToken = orderSubmitVo.getOrderToken();
//        String script = "if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end";
//        Long result = stringRedisTemplate.execute(new DefaultRedisScript<>(script, Long.class), Collections.singletonList(OrderConstant.USER_ORDER_TOKEN_PREFIX + memberVo.getId()), orderToken);
//        if(result == 1) {
//            submitOrderResponseVo.setCode(0);
//            // 创建订单
//
//        }else {
//            submitOrderResponseVo.setCode(1);
//        }
//        return submitOrderResponseVo;
//    }


//    private OrderCreateTo createOrder() {
//        OrderCreateTo orderCreateTo = new OrderCreateTo();
//        MemberVo memberVo = OrderInterceptor.threadLocal.get();
//        OrderSubmitVo orderSubmitVo = threadLocal.get();
//        String orderSn = IdWorker.getTimeId();
//        OrderEntity orderEntity = new OrderEntity();
//        orderEntity.setMemberId(memberVo.getId());
//        orderEntity.setOrderSn(orderSn);
//        R r = wareFeginService.getFare(orderSubmitVo.getAddrId());
//        if(r.getCode() == 0) {
//            FareVo fareVo = r.getData(new TypeReference<FareVo>() {});
//            orderEntity.setFreightAmount(fareVo.getFare());
//            orderEntity.setBillReceiverPhone(fareVo.getMemberReceiveAddressVo().getPhone());
//            orderEntity.setReceiverName(fareVo.getMemberReceiveAddressVo().getName());
//            orderEntity.setReceiverDetailAddress(fareVo.getMemberReceiveAddressVo().getDetailAddress());
//            orderEntity.setReceiverCity(fareVo.getMemberReceiveAddressVo().getCity());
//            orderEntity.setReceiverProvince(fareVo.getMemberReceiveAddressVo().getProvince());
//            orderEntity.setReceiverRegion(fareVo.getMemberReceiveAddressVo().getRegion());
//        }
//        List<OrderItemVo> cartItemList = cartFeignService.getCartItemList();
//        if(cartItemList != null && cartItemList.size() > 0) {
//            cartItemList.stream().map(item -> {
//                OrderItemEntity orderItemEntity = new OrderItemEntity();
//                orderItemEntity.setOrderSn(orderSn);
//                orderItemEntity.setSkuId(Long.parseLong(item.getSkuId()));
//                orderItemEntity.setSkuPic(item.getImage());
//                orderItemEntity.set
//            })
//        }
//        List<OrderItemEntity> orderItems = new ArrayList<>();

}